這篇整理一些先前使用 GSAP 時遇到的問題
0
,兔子的 x 在 1秒
中移動到 100
bunny.x = 0;
gsap.to(bunny, {duration: 1, x: 100});
問題: 當執行到一半時再觸發一次補間,並且 目標值改變 (通常是再次觸發了事件)。此時的結果為?
選項1: 堆疊 - 跑完原本 1秒 x 到 100的動態,再跑新增的 1秒 x 到 -100的動態;總時間為 2
秒
選項2: 覆寫 - 從 0.5秒
開始跑 1秒 x 到 -100的動態;總時間為 1.5
秒
gsap.to(bunny, {duration: 1, x: 100});
setTimeout(()=>{
gsap.to(bunny, {duration: 1, x: -100});
}, 500);
答案: 2,直接覆寫
,結束時間為覆寫時設定的時間,不會累加
調整: 覆寫動態與一開始的動態完全相同
結果: 覆寫動態觸發時, x 當下的值是 90
,速度會 突然變很慢
10
/s,(x 由 0
漸變到 90
)1
/s,(x 由 90
漸變到 100
)[ Demo1 ]
bunny.x = 0;
gsap.to(bunny, {duration: 1, x: 100});
setTimeout(()=>{
gsap.to(bunny, {duration: 1, x: 100});
}, 900);
gsap.to(bunny, {
duration: 1,
x: 100,
ease:"none",
onStart:()=>{
console.log("Start");
},
onComplete:()=>{
console.log("Complete");
}
});
bunny.isTweening = false;
function tweenBunny(){
// 如果兔子正在移動,就不接著繼續的補間動態
if (bunny.isTweening === true) {return};
gsap.to(bunny,
{
duration: 1,
x: Math.random() * 400,
y: Math.random() * 400,
onStart:()=>{
bunny.isTweening = true;
},
onComplete:()=>{
bunny.isTweening = false;
}
});
};
// 按鈕按下時執行 tweenBunny
btn.on("pointerdown", ()=>{
tweenBunny();
});
[ Demo2 ]
這是其中一種可行也方便做的方法,還有許多情境與作法,目前先不討論
若是希望新增的動態可以堆疊在原本的動態之後,可使用 Timeline
一樣的動態:
準備: 兔子的 x 為 0
,兔子的 x 在 1秒
中移動到 100
bunny.x = 0;
gsap.to(bunny, {duration: 1, x: 100});
問題: 當 0.5
秒的時後,突然指定兔子的 x 屬性,這時的動態會如何?
選項1: 停止補間動態,兔子停在 x: -100
位置
選項2: 兔子在 x: -100
一瞬間,然後繼續跑
// 這邊特別不使用 gsap 內建的方法以比較結果
setTimeout(()=>{
bunny.x = -100;
}, 500);
答案: 2,並不會覆寫原本的補間動態
用 gsap.to() 指定的動態,就用 gsap.killTweensOf() 來停止
gsap.to(bunny, {duration: 1, x: 100, y:100, ease:"none", onComplete: function(){
console.log('onComplete');
}});
setTimeout(()=>{
// 直接停掉 gsap.to(bunny, {...}) 所有行為,且不觸發 onComplete
gsap.killTweensOf(bunny);
gsap.set(bunny, {x: -100});
}, 500);
setTimeout(()=>{
// 停掉 gsap.to(bunny, {x: 100}) 的補間動畫,
// 由於還有 y 補間動畫,會觸發 onComplete
gsap.killTweensOf(bunny, {x: true});
gsap.set(bunny, {x: -100});
}, 500);
版本: gsap 1.20.3
直接用 TweenMax.set() 就會停止原本的補間動畫
TweenMax.to(bunny, 1, {x: 100, y: 100, onComplete: function(){
console.log("onComplete")
}});
setTimeout(()=>{
// x 與 y 皆覆寫,不會觸發 onComplete
TweenMax.set(bunny, {x: -100, y:0 });
}, 500);
setTimeout(()=>{
// 只覆寫 x,y 的補間動態保留,仍會觸發 onComplete
TweenMax.set(bunny, {x: -100 });
}, 500);
今日心得:
- 舊版 TweenMax 就很好用也夠用,我持續使用了滿久的時間
- gsap3 改版新增了很多有趣的功能,趁這個機會更新
- scrolltrigger 這個 plugin 非常有趣,一直想搭配 PixiJS 做個什麼
其他參考資料: